/**
 * JAVACC DEMO 1.0
 * @copy right dwusoft company All rights reserved. 
 * @Package com.apache.bid.common  
 */
package com.apache.bid.common;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.apache.api.vo.ResultEntity;
import com.apache.api.vo.ResultMsg;
import com.apache.bid.common.cache.BidCacheFactory;
import com.apache.bid.common.cache.BidCacheManager;
import com.apache.bid.common.vo.BidItemCacheVo;
import com.apache.bid.entity.BidApply;
import com.apache.bid.entity.BidInfoBaojia;
import com.apache.bid.entity.BidItem;
import com.apache.bid.entity.BidItemPrice;
import com.apache.bid.entity.BidItemVip;
import com.apache.bid.entity.BidPub;
import com.apache.database.model.Page;
import com.apache.rpc.client.RpcProtoclClient;
import com.apache.tools.DateUtils;
import com.apache.tools.StrUtil;
import com.apache.uct.common.LoginUser;
import com.apache.uct.common.ToolsUtil;

/**
 * description:  统一处理报价工具类
 * @author Hou Dayu 创建时间：2016-4-28  
 * 
 */
public class BidHallUtil {

	private static BidHallUtil instance;

	private BidHallUtil() {
	}

	public static BidHallUtil getInstance() {
		if (null == instance) {
			instance = new BidHallUtil();
		}
		return (instance);
	}

	/**
	 * description:  统一写报价操作
	 * @param params 方法参数
	 * @param msg    返回对象
	 * @param pub     pub对象
	 * @param myPrice 当前报价
	 * @param status  当前状态
	 * @param bidMode 竞价方式
	 */
	public ResultMsg bidSend(Map<String, Object> params, ResultMsg msg, BidPub pub, String myPrice, String status,
			String bidMode) {
		ResultEntity entity = new ResultEntity();
		params.put("itemStatus", status);
		switch (BidModeEnum.getName(bidMode)) {
		case JTZX://多次正向 
			params.put("myPrice", myPrice);
			entity = RpcProtoclClient.getInstance().doService("wbdCacheService", "syncJingjiaSave", params,
					BidCommonUtil.getInstance().getInterfaceRegister(pub.getBjServer(), pub.getBjPort()));
			break;
		case JTFX://多次反向 
			params.put("myPrice", myPrice);
			entity = RpcProtoclClient.getInstance().doService("wbdCacheService", "syncJingjiaSave", params,
					BidCommonUtil.getInstance().getInterfaceRegister(pub.getBjServer(), pub.getBjPort()));
			break;
		case YCXASC://一次正向(只判断状态和启始价,直接写报价记录，价格加密)
			params.put("myPrice", TeaUtil.encryptByTea(myPrice));
			entity = RpcProtoclClient.getInstance().doService("wbdCacheService", "syncBaojiaSave", params,
					BidCommonUtil.getInstance().getInterfaceRegister(pub.getBjServer(), pub.getBjPort()));
			break;
		case YCXDESC://一次反向
			params.put("myPrice", TeaUtil.encryptByTea(myPrice));
			entity = RpcProtoclClient.getInstance().doService("wbdCacheService", "syncBaojiaSave", params,
					BidCommonUtil.getInstance().getInterfaceRegister(pub.getBjServer(), pub.getBjPort()));
			break;
		case FEJJZX://份额正向
			params.put("myPrice", TeaUtil.encryptByTea(myPrice));
			entity = RpcProtoclClient.getInstance().doService("wbdCacheService", "syncShareSave", params,
					BidCommonUtil.getInstance().getInterfaceRegister(pub.getBjServer(), pub.getBjPort()));
			break;
		case FEJJFX://份额反向
			params.put("myPrice", TeaUtil.encryptByTea(myPrice));
			entity = RpcProtoclClient.getInstance().doService("wbdCacheService", "syncShareSave", params,
					BidCommonUtil.getInstance().getInterfaceRegister(pub.getBjServer(), pub.getBjPort()));
			break;
		case HELAN://荷兰式竞价
			params.put("myPrice", myPrice);
			entity = RpcProtoclClient.getInstance().doService("wbdCacheService", "syncHeLanSave", params,
					BidCommonUtil.getInstance().getInterfaceRegister(pub.getBjServer(), pub.getBjPort()));
			break;
		}
		if ("false".equals(StrUtil.doNull(String.valueOf(entity.getEntity()), "false"))) {
			if ("false".equals(entity.getResult())) {
				msg = new ResultMsg("F", "服务器连接失败");
			} else {
				msg = new ResultMsg("F", entity.getMessage());
			}
		} else {
			msg = new ResultMsg("T", StrUtil.doNull(entity.getMessage(), "报价成功"));
		}
		return msg;
	}

	/**
	 * description:  获取标的变化信息
	 */
	@SuppressWarnings({ "rawtypes" })
	public Map<String, Object> bidGet(LoginUser loginUser, String itemId, String bidNum) {
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("ischange", false);
		data.put("applyStatus", '-');
		BidCacheManager cache = BidCacheFactory.getInstance().getCacheManager("itemPrice");
		boolean mark = cache.checkCacheObject(BidCacheManager.item_prefix + itemId);
		if (mark) {
			BidItemPrice cacheVo = (BidItemPrice) cache.getCacheCloneByKey(BidCacheManager.item_price_prefix + itemId);
			BidItemCacheVo itemVo = (BidItemCacheVo) cache.getCacheCloneByKey(BidCacheManager.item_prefix + itemId);
			if (ToolsUtil.isEmpty(cacheVo))
				return data;
			try {
				if (Constant.BIDMODE_YCXASC.equals(itemVo.getBidMode())
						|| Constant.BIDMODE_YCXDESC.equals(itemVo.getBidMode())) {
					cacheVo.setLastValue("0");
				}
				String bidTime = DateUtils.Now.fmt_yyyyMMdd_HHmmssSSS();
				String status = BidCommonUtil.getInstance().getStatus(cacheVo, bidTime);
				data.put("itemStatus", status);
				long spareTime = getSpareTime(status, cacheVo, bidTime, itemVo.getBidMode());
				data.put("spareTime", spareTime);
				data.put("price", cacheVo);
				String userEname = "";
				data.put("myLevel", "0");
				if (!ToolsUtil.isEmpty(loginUser)) {
					userEname = loginUser.getUserEname();
					String applyKey = "";
					if (Constant.SETYPE_HD.equals(itemVo.getSessionType())) {
						applyKey = BidCacheManager.apply_prefix + userEname + "_" + itemId;
					} else {
						applyKey = BidCacheManager.apply_prefix + userEname + "_" + itemVo.getSessionId();
					}
					BidApply applyVo = (BidApply) cache.getCacheCloneByKey(applyKey);
					if (applyVo != null) {
						data.put("applyStatus", applyVo.getStatus());
					}
					data.put("myLevel", getMyLevel(itemVo, loginUser.getUserEname()));
				}

				if (Constant.BIDMODE_YCXASC.equals(itemVo.getBidMode())
						|| Constant.BIDMODE_YCXDESC.equals(itemVo.getBidMode())
						|| Constant.BIDMODE_FEJJZX.equals(itemVo.getBidMode())
						|| Constant.BIDMODE_FEJJFX.equals(itemVo.getBidMode())) {
					data.put("ischange", true);
					setBaojiaInfo(userEname, data, cache, itemVo, cacheVo);
				} else {
					if (!cacheVo.getBidTimes().equals(bidNum) || "T".equals(itemVo.getvFlag())) {
						data.put("ischange", true);
						data.put("lastUser", cacheVo.getUserName());
						data.put("lastLevel", cacheVo.getLastRightLevel());
						List list = (List) cache.getCacheCloneByKey(BidCacheManager.jingjia_prefix + itemId);
						if (!ToolsUtil.isEmpty(list)) {
							int lsize = list.size();
							if (lsize > 5) {
								data.put("list", list.subList(0, 5));
							} else {
								data.put("list", list);
							}
						}
					}
				}
			} catch (Exception e) {
				data.put("ischange", false);
				data.put("price", cacheVo);
			}
		}
		return data;
	}

	/**
	 * description:  获取报价信息
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void setBaojiaInfo(String userEname, Map<String, Object> data, BidCacheManager cache,
			BidItemCacheVo itemVo, BidItemPrice cacheVo) {
		List list = new ArrayList();
		data.put("lastUser", "");
		data.put("lastLevel", StrUtil.doNull(cacheVo.getLastRightLevel(), "0"));
		if (Constant.getInstance().getItemConfig("statusStop").equals(itemVo.getItemStatus())) {
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("itemId", itemVo.getItemId());
			params.put("pageIndex", "1");
			params.put("pageSize", "5");
			BidPub pub = BidCommonUtil.getInstance().getBidPub(itemVo, cache);
			ResultEntity entity = RpcProtoclClient.getInstance().doService("wbdCacheService", "findBaojias", params,
					BidCommonUtil.getInstance().getInterfaceRegister(pub.getBjServer(), pub.getBjPort()));
			if ("true".equals(entity.getResult()) && !ToolsUtil.isEmpty(entity.getEntity())) {
				Page page = (Page) entity.getEntity();
				list.addAll(page.getPageObjects());
			}
			data.put("lastValue", cacheVo.getLastValue());
		} else {
			data.put("updateTimes", "0");
			if (ToolsUtil.isNotNull(userEname)) {
				Object obj = cache.getCacheCloneByKey(BidCacheManager.baojia_prefix + userEname + "_"
						+ itemVo.getItemId());
				if (!ToolsUtil.isEmpty(obj)) {
					if (Constant.BIDMODE_FEJJZX.equals(itemVo.getBidMode())
							|| Constant.BIDMODE_FEJJFX.equals(itemVo.getBidMode())) {//处理份额报价
						List<BidInfoBaojia> bjs = (List<BidInfoBaojia>) obj;
						for (BidInfoBaojia bj : bjs) {
							bj.setBidValue(TeaUtil.decryptByTea(bj.getBidValue()));
							list.add(bj);
							data.put("lastUser", bj.getUserName());
						}
						//list.addAll(bjs);
					} else {
						BidInfoBaojia baojia = (BidInfoBaojia) obj;
						baojia.setBidValue(TeaUtil.decryptByTea(baojia.getBidValue()));
						data.put("updateTimes", baojia.getUpdateTimes());
						list.add(baojia);
						data.put("lastUser", baojia.getUserName());
					}
				}
			}
		}
		if (!ToolsUtil.isEmpty(list)) {
			int lsize = list.size();
			if (lsize > 5) {
				data.put("list", list.subList(0, 5));
			} else {
				data.put("list", list);
			}
		}
	}

	/**
	 * description:  按标的ID获取全的item,price,vip信息
	 */
	@SuppressWarnings("rawtypes")
	public Map<String, Object> getItemById(LoginUser loginUser, String itemId) {
		Map<String, Object> data = new HashMap<String, Object>();
		BidCacheManager cache = BidCacheFactory.getInstance().getCacheManager("item");
		boolean mark = cache.checkCacheObject(BidCacheManager.item_prefix + itemId);
		data.put("itemId", itemId);
		data.put("myLevel", "0");
		if (!mark) {
			return data;
		}
		BidItemCacheVo cacheVo = (BidItemCacheVo) cache.getCacheCloneByKey(cache.item_prefix + itemId);
		BidItem itemCache = (BidItem) cacheVo;
		data.put("item", itemCache);
		BidItemPrice price = (BidItemPrice) cache.getCacheCloneByKey(cache.item_price_prefix + itemId);
		data.put("price", price);
		if (!ToolsUtil.isEmpty(loginUser)) {
			String applyKey = BidCacheManager.apply_prefix + loginUser.getUserEname() + "_";
			if (!Constant.SETYPE_HD.equals(cacheVo.getSessionType())) {
				data.put("apply", cache.getCacheCloneByKey(applyKey + cacheVo.getSessionId()));
			} else {
				data.put("apply", cache.getCacheCloneByKey(applyKey + cacheVo.getItemId()));
			}
			data.put("myLevel", getMyLevel(cacheVo, loginUser.getUserEname()));
		}
		return data;
	}

	private String getMyLevel(BidItemCacheVo itemVo, String userEname) {
		String myLevel = "0";
		if ("T".equals(itemVo.getIfRight()) || "T".equals(itemVo.getAllowEndPrio())) {//判断是否开启过程或事后行权
			String vipKey = BidCacheManager.item_vip_prefix + userEname + "_" + itemVo.getItemId();
			BidItemVip vip = (BidItemVip) BidCacheFactory.getInstance().getCacheManager("itemVip")
					.getCacheObjectByKey(vipKey);
			if (!ToolsUtil.isEmpty(vip)) {
				if ("T".equals(itemVo.getIfRight())) {
					myLevel = StrUtil.doNull(vip.getVipLevel(), "0");
				}
				if ("9".equals(vip.getVipLevel())) {
					if ("T".equals(itemVo.getAllowEndPrio())) {
						myLevel = vip.getVipLevel();
					} else {
						myLevel = "0";
					}
				}
			}
		}
		return myLevel;
	}

	/**
	 * description:  获取份额报价竞得列表
	 */
	public List<Map<String, String>> getFeBaojiaResult(String itemNums, String bidMode, List<BidInfoBaojia> list) {
		List<Map<String, String>> result = new ArrayList<Map<String, String>>();
		long itemNum = Long.valueOf(StrUtil.doNull(itemNums, "1"));
		long total = 0l;
		boolean mark = Constant.BIDMODE_FEJJZX.equals(bidMode) ? true : false;
		String lastValue = "0";
		long nowTime = 0;
		long upNum = 0;
		Collections.sort(list, new Comparator<BidInfoBaojia>() {//按价格排序
					public int compare(BidInfoBaojia arg0, BidInfoBaojia arg1) {
						return arg0.getBidValue().compareTo(arg1.getBidValue());
					}
				});
		try {
			List<BidInfoBaojia> bjs = new ArrayList<BidInfoBaojia>();
			for (BidInfoBaojia bj : list) {//筛选最后竞得人 
				BigDecimal myPrice = new BigDecimal(bj.getBidValue());
				BigDecimal bidValue = new BigDecimal(lastValue);
				long num = Long.valueOf(bj.getBidNum());
				if (mark) {
					if (myPrice.compareTo(bidValue) > 0) {//正向
						lastValue = bj.getBidValue();
					} else if (myPrice.compareTo(bidValue) < 0) {
						continue;
					}
				} else {
					if (myPrice.compareTo(bidValue) < 0 || "0".equals(lastValue)) {//反向
						lastValue = bj.getBidValue();
					} else if (myPrice.compareTo(bidValue) > 0) {
						continue;
					}
				}
				if (myPrice == bidValue) {
					long bidTime = BidCommonUtil.getMillTime(bj.getBidTime(), "yyyy-MM-dd HH:mm:ss");
					if (bidTime < nowTime) {
						lastValue = bj.getBidValue();
						total = total - upNum;
					}
				}
				if (total > itemNum) {
					long count = total - itemNum;
					bj.setBidNum(String.valueOf(num - count));
					bjs.add(bj);
					break;
				} else if (total == itemNum) {
					bjs.add(bj);
					break;
				}
				nowTime = BidCommonUtil.getMillTime(bj.getBidTime(), "yyyy-MM-dd HH:mm:ss");
				total = total + num;
				upNum = num;
				bjs.add(bj);
			}

			int i = 0;
			Map<String, Integer> user = new HashMap<String, Integer>();
			for (BidInfoBaojia bj : bjs) {
				Map<String, String> map = null;
				if (user.containsKey(bj.getUserName())) {
					map = result.get(user.get(bj.getUserName()));
					result.remove(map);
				} else {
					map = new HashMap<String, String>();
					user.put(bj.getUserName(), i);
					i++;
				}
				int bjNum = Integer.valueOf(StrUtil.doNull(map.get("bidNum"), "0"));
				map.put("userName", bj.getUserName());
				map.put("bidNum", String.valueOf(bjNum + Integer.valueOf(bj.getBidNum())));
				map.put("lastValue", lastValue);
				map.put("bidTime", bj.getBidTime());
				if (user.containsKey(bj.getUserName())) {
					int cou = user.get(bj.getUserName());
					result.add(cou, map);
				} else {
					result.add(map);
				}
			}
		} catch (Exception e) {
		}
		return result;
	}

	/**
	 * description:  计算结束时间
	 */
	public long getSpareTime(String itemStatus, BidItemPrice price, String bidTime, String bidMode) {
		long nowTime = BidCommonUtil.getMillTime(bidTime, "yyyy-MM-dd HH:mm:ss:SSS");
		Long toTimeLong = 0l;
		String closeTime = price.getCloseTime();
		if (Constant.BIDMODE_HELAN.equals(bidMode)) {
			closeTime = price.getReductionCloseTime();
		}
		if (Constant.getInstance().getItemConfig("unStart").equals(itemStatus)) {
			toTimeLong = BidCommonUtil.getMillTime(price.getOpenTime(), "yyyy-MM-dd HH:mm:ss") - nowTime;
		} else if (Constant.getInstance().getItemConfig("freeOffer").equals(itemStatus)) {
			toTimeLong = BidCommonUtil.getMillTime(price.getFirstBidTime(), "yyyy-MM-dd HH:mm:ss") - nowTime;
		} else if (Constant.getInstance().getItemConfig("limitedOffer").equals(itemStatus)) {
			toTimeLong = BidCommonUtil.getMillTime(closeTime, "yyyy-MM-dd HH:mm:ss") - nowTime;
		} else if (Constant.getInstance().getItemConfig("increase").equals(itemStatus)) {
			BidItemCacheVo item = (BidItemCacheVo) BidCacheFactory.getInstance().getCacheManager("item")
					.getCacheObjectByKey(BidCacheManager.item_prefix + price.getItemId());
			long addTimes = Integer.valueOf(item.getAllowAddTime()) * 60 * 1000
					+ BidCommonUtil.getMillTime(closeTime, "yyyy-MM-dd HH:mm:ss");
			toTimeLong = addTimes - nowTime;
		} else if (Constant.getInstance().getItemConfig("exercise").equals(itemStatus)) {
			BidItemCacheVo item = (BidItemCacheVo) BidCacheFactory.getInstance().getCacheManager("item")
					.getCacheObjectByKey(BidCacheManager.item_prefix + price.getItemId());
			long addTimes = Integer.valueOf(item.getAllowAddTime()) * 60 * 1000
					+ Integer.valueOf(item.getAllowPrioTime()) * 60 * 1000
					+ BidCommonUtil.getMillTime(closeTime, "yyyy-MM-dd HH:mm:ss");
			toTimeLong = addTimes - nowTime;
		} else {
			return 0l;
		}
		if (toTimeLong < 0)
			toTimeLong = 0l;
		return toTimeLong;
	}

	/**
	 * description:  获取访问IP
	 * @param request 当前请求
	 * @return   
	 */
	public String getUserIp(HttpServletRequest request) {
		String ip = "";
		try {
			ip = request.getHeader("x-forwarded-for");
			if (ToolsUtil.isNull(ip) || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader("Proxy-Client-IP");
			}
			if (ToolsUtil.isNull(ip) || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader("WL-Proxy-Client-IP");
			}
			if (ToolsUtil.isNull(ip) || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getRemoteAddr();
			}
			if (ToolsUtil.isNotNull(ip) && ip.length() > 32) {
				ip = ip.substring(0, 32);
			}
		} catch (Exception e) {
		}
		return ip;
	}
}
